package main

import (
	"fmt"
	"strconv"
)

func main() {
	/*
        有缓冲区的通道：

		非缓冲通道：make(chan T)
			一次发送，一次接收，都是阻塞的
		缓冲通道：make(chan T, capacity)
			发送：缓冲区的数据满了，才会阻塞
			接收：缓冲区的数据空了，才会阻塞

            缓冲通道允许发送和接收端的数据获取处于异步的状态，就是说发送端的数据可以放在缓冲区里面，等待接收端去获取数据，而不是立刻需要去接收端获取数据。
                所以也称为 “异步通道”。
	*/
	ch1 := make(chan int)           //非缓冲通道
	fmt.Println(len(ch1), cap(ch1)) //0 0
	//ch1 <- 100                      //阻塞式的，需要有其他的goroutine解除阻塞，否则deadlock

	ch2 := make(chan int, 5)        //缓冲通道，缓冲区的大小是 5
	fmt.Println(len(ch2), cap(ch2)) // 0 5

	ch2 <- 100
	fmt.Println(len(ch2), cap(ch2)) //1 5
	ch2 <- 200
	ch2 <- 300
	ch2 <- 400
	ch2 <- 500
	fmt.Println(len(ch2), cap(ch2)) //5 5
	//ch2 <- 600                      //发生死锁

	fmt.Println("-----------------------------")
	ch3 := make(chan string)
	go sendData3(ch3)

	for {
		v, ok := <-ch3
		if !ok {
			fmt.Println("读完了。。。", ok)
			break
		}
		fmt.Println("\t读取的数据是：", v)
	}
	fmt.Println("main...over...")

}

func sendData3(ch chan string) {
	for i := 0; i < 10; i++ {
		ch <- "数据" + strconv.Itoa(i)
		fmt.Println("子goroutine中写出第 %d 个数据\n", i)
	}
	close(ch)
}
